package com.bicon.base.data.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bicon.base.data.common.tools.DateUtil;

public class FileUtil {

	private static Logger logger = LoggerFactory.getLogger(FileUtil.class);

	public static List<String> ergodic(File file, List<String> resultFileName) {
		File[] files = file.listFiles();
		if (files == null)
			return resultFileName;// 判断目录下是不是空的
		for (File f : files) {
			if (f.isDirectory()) {// 判断是否文件夹
				// resultFileName.add(f.getPath());
				ergodic(f, resultFileName);// 调用自身,查找子目录
			} else
				resultFileName.add(f.getName());
		}
		return resultFileName;
	}

	public static String getFileName(String filePath) {
		String fileName = "";
		if (filePath == null || "".equals(filePath)) {
			return null;
		}
		String[] pathArr = filePath.replaceAll("\\\\", "/").split("/");
		if (pathArr.length > 1) {
			fileName = pathArr[pathArr.length - 1];
		}
		return fileName;
	}

	public static String getFileDESKey(int index, String mechanismNo,
			String fileNme, String version, String fileType, String locafilePath) {
		String desKey = null;
		try {
			String fileKeyName = locafilePath + mechanismNo + "/" + fileNme
					+ version + "." + fileType;
			desKey = getDesKey(index, fileKeyName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return desKey;
	}

	private static String getDesKey(int index, String fileName) {
		List<String> list = readFileByLines(fileName);
		if (list != null && list.size() > index) {
			return list.get(index);
		}
		return null;
	}

	public static List<String> readFileByLines(String fileName) {
		List<String> keyList = new ArrayList<String>();
		File file = new File(fileName);
		if (!file.exists()) {
			return null;
		}
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;
			int line = 1;
			while ((tempString = reader.readLine()) != null) {
				if ("".equals(tempString.trim())) {// 在Windows环境下读取txt文件，每行之间会多出一个空行
					continue;
				}
				// 显示行号
				keyList.add(line - 1, tempString);
				line++;
			}
			//reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return keyList;
	}

	/**
	 * 创建年月日对应文件夹
	 */
	public static String createDateDirectory(String initDir) {
		String directory = initDir;
		// Calendar calendar = Calendar.getInstance();
		// int year = calendar.get(Calendar.YEAR);
		// int month = calendar.get(Calendar.MONTH)+1;
		// int day = calendar.get(Calendar.DAY_OF_MONTH);
		// directory = initDir + "/" + year + "/" + month + "/" + day ;
		String currentDay = DateUtil.now("yyyyMMdd");
		directory = initDir + "/" + currentDay;
		File file = new File(directory);
		if (!file.exists()) {
			file.mkdirs();
		}
		return directory;
	}

	/**
	 * 移动指定文件夹内的全部文件
	 *
	 * @param fromDir
	 *            要移动的文件目录
	 * @param toDir
	 *            目标文件目录
	 * @throws Exception
	 */
	public void fileMove(String from, String to) throws Exception {
		try {
			File dir = new File(from);
			// 文件一览
			File[] files = dir.listFiles();
			if (files == null)
				return;
			// 目标
			File moveDir = new File(to);
			if (!moveDir.exists()) {
				moveDir.mkdirs();
			}
			// 文件移动
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					fileMove(files[i].getPath(), to + "\\" + files[i].getName());
					// 成功，删除原文件
					files[i].delete();
				}
				File moveFile = new File(moveDir.getPath() + "\\"
						+ files[i].getName());
				// 目标文件夹下存在的话，删除
				if (moveFile.exists()) {
					moveFile.delete();
				}
				files[i].renameTo(moveFile);
			}
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 删除文件夹里面的文件
	 * @param localPath
	 */
	public static void deleteFile(String localPath){
		File file = new File(localPath);
//		File[] files = file.listFiles();
//		for (int i = 0; i < files.length; i++) {
//			files[i].delete();
//		}
		try {
			FileUtils.deleteDirectory(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void uploadFileToFtp(String serverIp, String port,
			String user, String passWord, String localPath, String ftpPath)
			throws Exception {
		File f = new File(localPath);

		FtpUtil.uploadFile(f.getName(), serverIp, Integer.parseInt(port), user,
				passWord, ftpPath, new FileInputStream(f));

	}

	public static void copyFile(File fromFile, File toFile) {
		InputStream is = null;
		FileOutputStream fos = null;
		try {
			if (!fromFile.exists()) {
				return;
			}
			 is = new FileInputStream(fromFile);// 创建文件输入流
			 fos = new FileOutputStream(toFile);// 文件输出流
			byte[] buffer = new byte[1024];// 字节数组
			while (is.read(buffer) != -1) {// 将文件内容写到文件中
				fos.write(buffer);
			}
			
		} catch (Exception e) {
			logger.error("复制整个文件夹内容操作出错,错误原因:{}", e.fillInStackTrace());
			e.printStackTrace();
		}finally{
			closeResource(is,fos);
		}
	}
	
	/**
	 * 
	 * @Title: closeResource 
	 * @Description: 关闭资源 
	 * @param @param is
	 * @param @param fos    设定文件 
	 * @return void    返回类型 
	 * @throws
	 */
	private static void closeResource(InputStream is,FileOutputStream fos){
		try{
			if(null != is){
				is.close();// 输入流关闭	
			}
			if(null != fos){
				fos.flush();
				fos.close();// 输出流关闭
				
			}
			
		}catch(IOException ex){
			
		}
	}

	/**
	 * 复制整个文件夹内容
	 * 
	 * @param oldPath
	 *            String 原文件路径 如：c:/fqf
	 * @param newPath
	 *            String 复制后路径 如：f:/fqf/ff
	 * @return boolean
	 */
	public void copyFolder(String oldPath, String newPath) {

		try {
			(new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
			File a = new File(oldPath);
			String[] file = a.list();
			File temp = null;
			for (int i = 0; i < file.length; i++) {
				if (oldPath.endsWith(File.separator)) {
					temp = new File(oldPath + file[i]);
				} else {
					temp = new File(oldPath + File.separator + file[i]);
				}

				if (temp.isFile()) {
					FileInputStream input = new FileInputStream(temp);
					FileOutputStream output = new FileOutputStream(newPath
							+ "/" + (temp.getName()).toString());
					byte[] b = new byte[1024 * 5];
					int len;
					while ((len = input.read(b)) != -1) {
						output.write(b, 0, len);
					}
					output.flush();
					output.close();
					input.close();
				}
				if (temp.isDirectory()) {// 如果是子文件夹
					copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
				}
			}
		} catch (Exception e) {
			logger.error("复制整个文件夹内容操作出错,错误原因:{}", e.fillInStackTrace());
			e.printStackTrace();

		}
	}

	/*
	 * 复制文件.
	 * 
	 * @param sourceFileName
	 * 
	 * @param targetFile
	 * 
	 * @throws IOException
	 */
	public void copyFile(String sourceFileName, String sourceDir,
			String targetDir) throws IOException {
		ByteArrayInputStream in = null;
		ByteArrayOutputStream fos = new ByteArrayOutputStream();
		FTPClient ftpClient = new FTPClient();
		try {

			ftpClient.setBufferSize(1024 * 2);
			// 变更工作路径
			ftpClient.changeWorkingDirectory(sourceDir);
			// 设置以二进制流的方式传输
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
			// 将文件读到内存中
			ftpClient.retrieveFile(new String(sourceFileName.getBytes("GBK"),
					"iso-8859-1"), fos);
			in = new ByteArrayInputStream(fos.toByteArray());
			if (in != null) {
				ftpClient.changeWorkingDirectory(targetDir);
				ftpClient.storeFile(new String(sourceFileName.getBytes("GBK"),
						"iso-8859-1"), in);
			}
		} finally {
			// 关闭流
			if (in != null) {
				in.close();
			}
			if (fos != null) {
				fos.flush();
				fos.close();
			}
		}
	}

	/**
	 * 复制单个文件
	 * 
	 * @param oldPath
	 *            String 原文件路径 如：c:/fqf.txt
	 * @param newPath
	 *            String 复制后路径 如：f:/fqf.txt
	 * @return boolean
	 */
	public void copyFile(String oldPath, String newPath) {
//		InputStream inStream = null;
//		FileOutputStream fs = null;
//		try {
//			// int bytesum = 0;
//			int byteread = 0;
//			File oldfile = new File(oldPath);
//			if (oldfile.exists()) { // 文件存在时
//				inStream = new FileInputStream(oldPath); // 读入原文件
//				fs = new FileOutputStream(newPath);
//				byte[] buffer = new byte[1024 * 2];
//				// int length;
//				while ((byteread = inStream.read(buffer)) != -1) {
//					// bytesum += byteread; //字节数 文件大小
//					// System.out.println(bytesum);
//					fs.write(buffer, 0, byteread);
//				}
//				// inStream.close();
//				// fs.close();
//			}
//		} catch (Exception e) {
//			logger.error("复制单个文件操作,错误原因:{}", e.fillInStackTrace());
//			e.printStackTrace();
//
//		} finally {
//			try {
//				if (null != fs) {
//					fs.flush();
//				}
//			} catch (IOException ex) {
//				logger.error("文件流发生异常,{}", ex.fillInStackTrace());
//			}
//			IOUtils.closeQuietly(fs);
//			IOUtils.closeQuietly(inStream);
//		}
		File srcFile = new File(oldPath);
		File dstFile = new File(newPath);
		if(!srcFile.exists()){
			throw new RuntimeException("源文件不存在");
		}
		try {
			FileUtils.copyFile(srcFile, dstFile);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 复制文件夹.
	 * 
	 * @param sourceDir
	 * @param targetDir
	 * @throws IOException
	 */
	public void copyDirectiory(String sourceDir, String targetDir)
			throws IOException {
		// // 新建目标目录
		// if (!existDirectory(targetDir)) {
		// createDirectory(targetDir);
		// }
		FTPClient ftpClient = new FTPClient();
		// 获取源文件夹当前下的文件或目录
		// File[] file = (new File(sourceDir)).listFiles();
		FTPFile[] ftpFiles = ftpClient.listFiles(sourceDir);
		for (int i = 0; i < ftpFiles.length; i++) {
			if (ftpFiles[i].isFile()) {
				copyFile(ftpFiles[i].getName(), sourceDir, targetDir);
			} else if (ftpFiles[i].isDirectory()) {
				copyDirectiory(sourceDir + "/" + ftpFiles[i].getName(),
						targetDir + "/" + ftpFiles[i].getName());
			}
		}
	}
	
	/*************************************读取zip文件里面的数据**********************************************/
	
	public static final int BUFFER_SIZE = 1024;

    /**
     * 解压 zip 文件
     * @param zipFile zip 压缩文件
     * @param destDir zip 压缩文件解压后保存的目录
     * @return 返回 zip 压缩文件里的文件名的 list
     * @throws Exception
     */
    public static List<String> unZip(File zipFile, String destDir) throws Exception {
        // 如果 destDir 为 null, 空字符串, 或者全是空格, 则解压到压缩文件所在目录
        if(StringUtils.isBlank(destDir)) {
            destDir = zipFile.getParent();
        }

        destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
        ZipArchiveInputStream is = null;
        List<String> fileNames = new ArrayList<String>();
        InputStream inputStream = null;
        InputStream bufinputStream = null;
        OutputStream outputStream = null;
        try {
        	inputStream = new FileInputStream(zipFile);
        	bufinputStream = new BufferedInputStream(inputStream, BUFFER_SIZE) ;
        	
            is = new ZipArchiveInputStream(bufinputStream);
            ZipArchiveEntry entry = null;
            while ((entry = is.getNextZipEntry()) != null) {
                fileNames.add(entry.getName());

                if (entry.isDirectory()) {
                    File directory = new File(destDir, entry.getName());
                    directory.mkdirs();
                } else {
                    OutputStream os = null;
                    try {
                    	outputStream = new FileOutputStream(new File(destDir, entry.getName()));
                        os = new BufferedOutputStream(outputStream, BUFFER_SIZE);
                        IOUtils.copy(is, os);
                    } finally {
                        IOUtils.closeQuietly(os);
                    }
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(bufinputStream);
            if(null != outputStream){
            	outputStream.flush();
            	IOUtils.closeQuietly(outputStream);
            }
            
            
        }

        return fileNames;
    }
	/**字符串不足位数
	  *左补0
	  * @param str
	  * @param strLength
	  */
	public static String addZeroForStr_L(String str, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				//sb.append(str).append("0");//右补
				if (!StringTools.isBlankOrNull(str)) {
					sb.append("0").append(str);//左补
				} else {
					sb.append("0");
				}
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}
	/**
	 * 获取字符串长度(字符串中可包含中文)
	 * @param str
	 * @return
	 */
	private static int strLength(String str){
		int valueLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        /* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
        if (!StringTools.isBlankOrNull(str)) {
        	for (int i = 0; i < str.length(); i++) {
                /* 获取一个字符 */
                String temp = str.substring(i, i + 1);
                /* 判断是否为中文字符 */
                if (temp.matches(chinese)) {
                    /* 中文字符长度为2 */
                    valueLength += 2;
                } else {
                    /* 其他字符长度为1 */
                    valueLength += 1;
                }
            }
        }
        
        return valueLength;
	}
	
    /**
     * 解压 zip 文件
     * @param zipfile zip 压缩文件的路径
     * @param destDir zip 压缩文件解压后保存的目录
     * @return 返回 zip 压缩文件里的文件名的 list
     * @throws Exception
     */
    public static List<String> unZip(String zipfile, String destDir) throws Exception {
        File zipFile = new File(zipfile);
        return unZip(zipFile, destDir);
    }

    
    /** 
     * 打包文件 
     * @param files 文件或文件夹的集合 
     * @param out 输出的zip文件 
     */  
    public static void zip(File[] files, File out) {  
        if (files != null) {  
            Map<String, File> map = new HashMap<String, File>();  
            for (File f : files) {  
                list(f, null, map);  
            }  
            if (!map.isEmpty()) {  
                try {  
                    ZipArchiveOutputStream zaos = new ZipArchiveOutputStream(out);  
                    for (Map.Entry<String, File> entry : map.entrySet()) {  
                        File file = entry.getValue();  
                        ZipArchiveEntry zae = new ZipArchiveEntry(file, entry.getKey());  
                        zaos.putArchiveEntry(zae);  
                        InputStream is = new FileInputStream(file);  
                        byte[] b = new byte[1024 * 8];  
                        int i = -1;  
                        while ((i = is.read(b)) != -1) {  
                            zaos.write(b, 0, i);  
                        }  
                        is.close();  
                        zaos.closeArchiveEntry();  
                    }  
                    zaos.finish();  
                    zaos.close();  
                } catch (IOException ex) {  
                	logger.error(ex.getMessage(), ex);  
                }  
            }  
        }  
    }  
    
    private static void list(File f, String parent, Map<String, File> map) {  
        String name = f.getName();  
        if (parent != null) {  
            name = parent + "/" + name;//设置在zip包里的相对路径  
        }  
        if (f.isFile()) {  
            map.put(name, f);  
        } else if (f.isDirectory()) {  
            for (File file : f.listFiles()) {  
                list(file, name, map);  
            }  
        }  
    }  
    
    public static void main(String[] args) throws Exception {
    	FileUtil.deleteFile("E:/LCTData/OUTPUT/80000002");
       // List<String> names = unZip("f:/XF80000004000000012017082101.zip", "f:/test");
        //System.out.println(names); 
    	//File[] files, File out
    	//File [] file = {new File("d:\\soft\\CentOS-7-x86_64-DVD-1511.iso")};
    	//zip(file,new File("f:/CentOS-7-x86_64-DVD-1511.zip"));
    }
    
   

}
